package com.zz.bid.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zz.bid.exception.base.BidException;
import com.zz.bid.mapper.BidFlowMapper;
import com.zz.bid.mapper.BidMapper;
import com.zz.bid.pojo.entity.BidFlowEnum;
import com.zz.bid.pojo.query.BidQuery;
import com.zz.bid.pojo.to.BidDesc;
import com.zz.bid.pojo.to.BidFlowDetails;
import com.zz.bid.util.BidStatusEnum;
import com.zz.bid.util.ExcelUtil;
import com.zz.bid.util.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author chenkehan created at 2020/4/4 6:26 下午
 */
@Service
@Slf4j
public class BidService {

    @Autowired
    private BidMapper bidMapper;

    @Autowired
    private BidFlowMapper flowMapper;

    public void create(BidDesc bidDesc, String user) throws BidException {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            bidDesc.setBidStatus(BidStatusEnum.DEPOSITING);
            bidDesc.setWinBid(false);
            bidDesc.setLastUpdateUser(user);
            bidDesc.setLastUpdateTime(sdf.format(new Date()));
            bidMapper.create(bidDesc);
            // 先创建招标流程，再创建招标流程附件目录
            for (BidFlowEnum bidFlowEnum : BidFlowEnum.values()) {
                FileUtil.mkdir(FileUtil.getBidPath(bidDesc.getId(), bidFlowEnum.getFlowName()));
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            throw new BidException(e.getMessage());
        }
    }

    // public List<BidTO> search(BidTO bidTO) throws BidException {
    // try {
    // List<Bid> bidList = bidMapper.search(bidTO);
    // if (CollectionUtils.isEmpty(bidList)) {
    // return new ArrayList<>();
    // }
    // return bidList.stream().map(item ->
    // BidTO.builder().id(item.getId()).name(item.getName()).openDate(item.getOpenDate()).build()).collect(Collectors.toList());
    // } catch (Exception e) {
    // log.error(e.getMessage());
    // throw new BidException(e.getMessage());
    // }
    // }

    public void update(BidDesc bidDesc) throws BidException {
        try {
            bidMapper.update(bidDesc);
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new BidException(e.getMessage());
        }
    }

    public void updateStatus(Integer bidId, String user, BidStatusEnum status) throws BidException {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            BidDesc bidDesc = bidMapper.getBidDesc(bidId);
            bidDesc.setBidStatus(status);
            bidMapper.update(bidDesc);
            bidDesc.setLastUpdateTime(sdf.format(new Date()));
            bidDesc.setLastUpdateUser(sdf.format(""));
            bidMapper.update(bidDesc);
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new BidException(e.getMessage());
        }
    }

    public PageInfo<BidDesc> bidList(BidQuery bidQuery) throws BidException {
        try {
            PageHelper.startPage(bidQuery.getPageNo(), bidQuery.getPageSize());
            System.out.println(">>>>>>" + bidQuery.getStartOpenDate() + bidQuery.getEndOpenDate());
            List<BidDesc> bids = bidMapper.listBid(bidQuery);
            return new PageInfo<>(bids);
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new BidException(e.getMessage());
        }
    }

    public HSSFWorkbook export(BidQuery bidQuery) {
        List<BidDesc> bids = bidMapper.listBid(bidQuery);
        //excel标题
        String[] title = {"项目名称", "项目负责人", "审核人", "开标人", "是否含有技术文件", "开标时间", "是否中标", "保证金是否退回"};
        //sheet名
        String sheetName = "招投标信息表";
        String[][] content = new String[bids.size() + 1][title.length];
        for (int i = 0; i < bids.size(); i++) {
            BidDesc bidDesc = bids.get(i);
            content[i][0] = bidDesc.getName() + "";
            content[i][1] = bidDesc.getInCharge();
            content[i][2] = bidDesc.getAuditor();
            content[i][3] = bidDesc.getOpenBy();
            content[i][4] = bidDesc.isHasTech() ? "是" : "否";
            content[i][5] = bidDesc.getOpenDate();
            content[i][6] = bidDesc.getWinBid() ? "是" : "否";
            content[i][7] = bidDesc.getRefundInfo();
        }
        //创建HSSFWorkbook
        HSSFWorkbook wb = ExcelUtil.getHSSFWorkbook(sheetName, title, content, null);
        return wb;
    }

    public BidDesc bidDetails(int bidId) throws BidException {
        try {
            return bidMapper.getBidDesc(bidId);
        } catch (Exception e) {
            throw new BidException(e.getMessage());
        }
    }

    public void bidDelete(int bidId) throws BidException {
        try {
            bidMapper.deleteBid(bidId);
        } catch (Exception e) {
            throw new BidException(e.getMessage());
        }
    }

    @Transactional
    public void storeFile(int bidId, int flowId, String user, MultipartFile file) throws BidException {
        try {
            // update更新人和更新时间
            FileUtil.storeFile(file, FileUtil.getBidPath(bidId, BidFlowEnum.values()[flowId].getFlowName()));
            updateFlow(bidId, flowId, user);
        } catch (Exception e) {
            throw new BidException(e.getMessage());
        }
    }

    public byte[] loadfile(String fileName, int bidId, int flowId) throws BidException {
        try {
            BidDesc bidDesc = bidMapper.getBidDesc(bidId);
            String filePath = FileUtil.getBidPath(bidId, BidFlowEnum.values()[flowId].getFlowName());
            InputStream fis = new BufferedInputStream(new FileInputStream(filePath + File.separator + fileName));
            byte[] bs = new byte[fis.available()];
            fis.read(bs);
            fis.close();
            return bs;
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new BidException(e.getMessage());
        }
    }

    @Transactional
    public void deleteBidFile(Integer bidId, Integer flowId, String fileName, String user) throws BidException {
        try {
            String filePath = FileUtil.getBidPath(bidId, BidFlowEnum.values()[flowId].getFlowName());
            File file = new File(filePath + File.separator + fileName);
            if (file.exists() && file.isFile()) {
                file.delete();
                updateFlow(bidId, flowId, user);
            }
        } catch (Exception e) {
            throw new BidException(e.getMessage());
        }
    }

    private void updateFlow(Integer bidId, Integer flowId, String user) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        BidDesc bidDesc = bidMapper.getBidDesc(bidId);
        bidDesc.setLastUpdateTime(sdf.format(new Date()));
        bidDesc.setLastUpdateUser(user);
        bidMapper.update(bidDesc);

        BidFlowDetails flow = flowMapper.getBidFlow(bidId, flowId);
        flow.setLastUpdateTime(sdf.format(new Date()));
        flow.setLastUpdateUser(user);
        flowMapper.update(flow);
    }

    public Map<Integer, BidFlowDetails> getFlows(int bidId) {
        Map<Integer, BidFlowDetails> result = new HashMap<>();
        for (BidFlowEnum bidFlowEnum : BidFlowEnum.values()) {
            BidFlowDetails bidFlowDetails = flowMapper.getBidFlow(bidId, bidFlowEnum.getId());
            List<String> flowFileNames = new ArrayList<>();
            String path = FileUtil.getBidPath(bidId, bidFlowEnum.getFlowName());
            File fileDir = new File(path);
            File[] filelist = fileDir.listFiles();
            Assert.notNull(filelist, "file not valid");
            for (File file : filelist) {
                if (file.isFile()) {
                    flowFileNames.add(file.getName());
                }
            }
            bidFlowDetails.setFileNames(flowFileNames);
            result.put(bidFlowEnum.getId(), bidFlowDetails);
        }
        return result;
    }

    public BidFlowDetails getFlow(Integer bidId, Integer flowId) {
        BidFlowDetails bidFlowDetails = flowMapper.getBidFlow(bidId, flowId);
        List<String> flowFileNames = new ArrayList<>();
        String path = FileUtil.getBidPath(bidId, BidFlowEnum.values()[flowId].getFlowName());
        File fileDir = new File(path);
        File[] filelist = fileDir.listFiles();
        Assert.notNull(filelist, "file not valid");
        for (File file : filelist) {
            if (file.isFile()) {
                flowFileNames.add(file.getName());
            }
        }
        bidFlowDetails.setFileNames(flowFileNames);
        return bidFlowDetails;
    }
}
